package impl.comp;

import java.util.concurrent.Executors;

import impl.DataImpl;
import impl.LifeManagerImpl;
import impl.agentt.UnePresenceImpl;
import impl.agentt.enseignant.UnEnseignantImpl;
import impl.agentt.etudiant.UnEtudiantImpl;
import impl.agentt.pEns.BehaviourPEns;
import impl.agentt.pEtu.BehaviourPEtu;
import interfaces.IEmploiDuTemps;
import interfaces.agenttCreation.CreateEnseignantIface;
import interfaces.agenttCreation.CreateEtudiantIface;
import interfaces.agenttCreation.CreatePresenceIface;
import message.EDTMessage;
import mysticedt.Data;
import mysticedt.Database;
import mysticedt.Infr;
import mysticedt.LifeManager;
import mysticedt.PlagesHoraires;
import fr.irit.smac.may.lib.components.messaging.Sender;
import fr.irit.smac.may.lib.components.messaging.SenderImpl;
import fr.irit.smac.may.lib.components.messaging.receiver.AgentRef;
import fr.irit.smac.may.lib.components.messaging.receiver.Receiver;
import fr.irit.smac.may.lib.components.messaging.receiver.ReceiverImpl;
import fr.irit.smac.may.lib.components.meta.Forward;
import fr.irit.smac.may.lib.components.meta.ForwardImpl;
import fr.irit.smac.may.lib.components.scheduling.ExecutorService;
import fr.irit.smac.may.lib.components.scheduling.ExecutorServiceWrapperImpl;
import fr.irit.smac.may.lib.components.scheduling.Scheduler;
import fr.irit.smac.may.lib.components.scheduling.SchedulerImpl;

public class InfrImpl extends Infr {

	//ici je garde une référence vers chacunes des transverses.
	LifeManagerImpl lifemanager;
	ReceiverImpl<EDTMessage> referenceReceiver;
	SenderImpl<EDTMessage, AgentRef> referenceSender;
	SchedulerImpl scheduler;
	DataImpl datat;
	
	protected volatile long i = 0;

	@Override
	protected CreateEtudiantIface createEtudiantAgent() {
		return new CreateEtudiantIface() {
			
			public AgentRef createEtudiantAgent() {
				Etudiant agent = new Etudiant(new UnEtudiantImpl(),
						referenceReceiver.new AgentSide("Etu_"+i++),
						referenceSender.new AgentSide(),
						lifemanager.new AgentSide(), 
						scheduler.new AgentSide(),
						datat.new AgentSide());
				
				agent.start();
				return agent.referenceReceiver().me().pull();
			}
		};
	}

	@Override
	protected CreateEnseignantIface createEnseignantAgent() {
		return new CreateEnseignantIface() {
			
			public AgentRef createEnseignantAgent() {
				Enseignant agent = new Enseignant(new UnEnseignantImpl(),
						referenceReceiver.new AgentSide("Ens_"+i++),
						referenceSender.new AgentSide(),
						lifemanager.new AgentSide(), 
						scheduler.new AgentSide(),
						datat.new AgentSide());
				
				agent.start();
				return agent.referenceReceiver().me().pull();
			}
		};
	}

	
	@Override
	protected CreatePresenceIface createPresenceAgent() {
		return new CreatePresenceIface() {
			
			public AgentRef createPresenceEtudiantAgent() {
				Presence agent = new Presence(
						new UnePresenceImpl(new BehaviourPEtu()),
						
						referenceReceiver.new AgentSide("pEtu_"+i++),
						referenceSender.new AgentSide(),
						lifemanager.new AgentSide(), 
						scheduler.new AgentSide(),
						datat.new AgentSide());
				
				agent.start();
				return agent.referenceReceiver().me().pull();
			
			}
			
			public AgentRef createPresenceEnseignantAgent() {
				Presence agent = new Presence(
						new UnePresenceImpl(new BehaviourPEns()),
						
						referenceReceiver.new AgentSide("pEns_"+i++),
						referenceSender.new AgentSide(),
						lifemanager.new AgentSide(), 
						scheduler.new AgentSide(),
						datat.new AgentSide());
				
				agent.start();
				return agent.referenceReceiver().me().pull();
			
			}
		};
	}
	
	//transverses.
	@Override
	protected LifeManager make_lifeManager() {
		return lifemanager;
	}

	@Override
	protected Receiver<EDTMessage> make_referenceReceiver() {
		referenceReceiver = new ReceiverImpl<EDTMessage>();
		return referenceReceiver;
	}

	@Override
	protected Sender<EDTMessage, AgentRef> make_referenceSender() {
		referenceSender = new SenderImpl<EDTMessage, AgentRef>();
		return referenceSender;
	}

	@Override
	protected Scheduler make_scheduler() {
		scheduler = new  SchedulerImpl();
		return scheduler;
	}
	
	@Override
	protected Data make_data() {
		datat = new DataImpl();
		return datat;
	}


	
	//composants.

	@Override
	protected ExecutorService make_executor() {
		return new ExecutorServiceWrapperImpl(Executors.newFixedThreadPool(8));
	}

	@Override
	protected PlagesHoraires make_ph() {
		return new PlagesHorairesImpl();
	}

	@Override
	protected Database make_db() {
		// TODO Auto-generated method stub
		return null;
	}

}
